home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / progtool / c / egem_210 / egem / source / objcedit.c < prev    next >
C/C++ Source or Header  |  1995-11-25  |  23KB  |  1,060 lines

  1.  
  2. #ifndef SMALL_EGEM
  3.  
  4. #include "proto.h"
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8.  
  9. #ifndef __MINT_LIB__
  10. #include <stdlib.h>
  11. #endif
  12.  
  13. static char string_0[] = "ASCII-Table";
  14. static char string_1[] = " \x01" "\x02" "\x03" "\x04" "\x05" "\x06" "\x07" "\x08" "\x09" "\x0a" "\x0b" "\x0c" "\x0d" "\x0e" "\x0f" "\x10" "\x11" "\x12" "\x13" "\x14" "\x15" "\x16" "\x17" "\x18" "\x19" "\x1a" "\x1b" "\x1c" "\x1d" "\x1e" "\x1f" "";
  15. static char string_2[] = " !\"#$%&\'()*+,-./0123456789:;<=>?";
  16. static char string_3[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
  17. static char string_4[] = "`abcdefghijklmnopqrstuvwxyz{|}~\x7f" "";
  18. static char string_5[] = "\x80" "ü\x82" "\x83" "ä\x85" "\x86" "\x87" "\x88" "\x89" "\x8a" "\x8b" "\x8c" "\x8d" "Ä\x8f" "\x90" "\x91" "\x92" "\x93" "ö\x95" "\x96" "\x97" "\x98" "ÖÜ\x9b" "\x9c" "\x9d" "ß\x9f" "";
  19. static char string_6[] = "\xa0" "\xa1" "\xa2" "\xa3" "\xa4" "\xa5" "\xa6" "\xa7" "\xa8" "\xa9" "\xaa" "\xab" "\xac" "\xad" "\xae" "\xaf" "\xb0" "\xb1" "\xb2" "\xb3" "\xb4" "\xb5" "\xb6" "\xb7" "\xb8" "\xb9" "\xba" "\xbb" "\xbc" "\xbd" "\xbe" "\xbf" "";
  20. static char string_7[] = "\xc0" "\xc1" "\xc2" "\xc3" "\xc4" "\xc5" "\xc6" "\xc7" "\xc8" "\xc9" "\xca" "\xcb" "\xcc" "\xcd" "\xce" "\xcf" "\xd0" "\xd1" "\xd2" "\xd3" "\xd4" "\xd5" "\xd6" "\xd7" "\xd8" "\xd9" "\xda" "\xdb" "\xdc" "\xdd" "\xde" "\xdf" "";
  21. static char string_8[] = "\xe0" "\xe1" "\xe2" "\xe3" "\xe4" "\xe5" "\xe6" "\xe7" "\xe8" "\xe9" "\xea" "\xeb" "\xec" "\xed" "\xee" "\xef" "\xf0" "\xf1" "\xf2" "\xf3" "\xf4" "\xf5" "\xf6" "\xf7" "\xf8" "\xf9" "\xfa" "\xfb" "\xfc" "\xfd" "\xfe" "\xff" "";
  22. static char string_9[] = "Cancel";
  23.  
  24. static TEDINFO ascii_title =
  25.     { string_0, "", "", IBM, 0, TE_CNTR, 0x1180, 0, -1, 11, 1};
  26.  
  27. static OBJECT ascii_tree[] = {
  28.     { -1, 1, 13, G_BOX, NONE, OUTLINED,CAST (0x21141L), 0,512, 36,14 },
  29.     { 11, 2, 10, G_BOX, NONE, NORMAL,CAST (0xFF1101L), 2,3073, 32,777 },
  30.     { 3, -1, -1, (HEADER<<8)+G_BOXTEXT, NONE, NORMAL,CAST &ascii_title, 1,0, 13,1 },
  31.     { 4, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_1, 0,1, 32,1 },
  32.     { 5, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_2, 0,2, 32,1 },
  33.     { 6, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_3, 0,3, 32,1 },
  34.     { 7, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_4, 0,4, 32,1 },
  35.     { 8, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_5, 0,5, 32,1 },
  36.     { 9, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_6, 0,6, 32,1 },
  37.     { 10,-1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_7, 0,7, 32,1 },
  38.     { 1, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_8, 0,8, 32,1 },
  39.     { 13, 12, 12, G_BUTTON, SELECTABLE|DEFAULT|EXIT, NORMAL,CAST string_9, 22,3851, 12,1025 },
  40.     { 11, -1, -1, (HOTKEY<<8)+G_IBOX, NONE, NORMAL,CAST (0x43011100L), 3,512, 1,1 },
  41.     { 0, -1, -1, (FLYDIAL<<8)+G_IBOX, SELECTABLE|LASTOB, NORMAL,CAST (0x57011100L), 34,0, 2,1 },
  42. };
  43.  
  44. #define ASC0    3
  45. #define CANCEL    11
  46.  
  47. #define    HISTORY    20
  48.  
  49. static char history[HISTORY][MAX_EDIT];
  50. static int    hist_index;
  51.  
  52. static char umlaute[] = "_äöüÄÖÜß";
  53.  
  54. static int insert_char(DIAINFO *info,int scan);
  55. static void delete_char(DIAINFO *info,int index);
  56. static void insert_string(DIAINFO *info,char *str);
  57.  
  58. char *_edit_get_info(OBJECT *tree,int obj,int index,EDINFO *ed)
  59. {
  60.     reg OBJECT *obptr;
  61.     reg TEDINFO *ted;
  62.     reg char *edit,*masc,c,u='_';
  63.     reg int x,idx,width,pxy[4];
  64.  
  65.     if (obj<=0 || index<0)
  66.         return (NULL);
  67.  
  68.     obptr = &tree[obj];
  69.     ted = obptr->ob_spec.tedinfo;
  70.  
  71.     switch (ted->te_font)
  72.     {
  73.     case SMALL:
  74.         ed->cw = gr_sw;
  75.         ed->ch = gr_sh;
  76.         break;
  77.     case IBM:
  78.         ed->cw = gr_cw;
  79.         ed->ch = gr_ch;
  80.         break;
  81.     default:
  82.         v_set_text(ted->te_fontid,-ted->te_fontsize,FAIL,pxy);
  83.         ed->cw = pxy[0];
  84.         ed->ch = pxy[1];
  85.     }
  86.  
  87.     ed->text = ted->te_ptext;
  88.     ed->masc = masc = ted->te_ptmplt;
  89.     ed->valid = ted->te_pvalid;
  90.  
  91.     width = (int) strlen(masc);
  92.     width *= ed->cw;
  93.  
  94.     objc_offset(tree,obj,&ed->text_x,&ed->text_y);
  95.     ed->text_y += (obptr->ob_height - ed->ch)>>1;
  96.     ed->text_w = width;
  97.     ed->text_h = ed->ch;
  98.  
  99.     switch(ted->te_just)
  100.     {
  101.     case TE_RIGHT:
  102.         ed->text_x += obptr->ob_width-width;
  103.         break;
  104.     case TE_CNTR:
  105.         ed->text_x += (obptr->ob_width-width)>>1;
  106.         break;
  107.     }
  108.  
  109.     ed->edit_x = ed->text_x;
  110.     ed->edit_y = ed->text_y;
  111.     ed->edit_w = 0;
  112.     ed->edit_h = ed->text_h;
  113.  
  114.     while (*masc && *masc++!=u)
  115.         ed->edit_x += ed->cw;
  116.     masc--;
  117.     edit = masc;
  118.  
  119.     width = 0;
  120.     while (*masc!='\0')
  121.     {
  122.         width += ed->cw;
  123.         if (*masc++==u)
  124.             ed->edit_w = width;
  125.     }
  126.  
  127.     x = ed->crs_x = ed->edit_x;
  128.     ed->crs_y = ed->edit_y;
  129.  
  130.     idx = 0;
  131.     masc = edit;
  132.     while ((c=*masc++)!='\0')
  133.     {
  134.         if (c==u)
  135.         {
  136.             ed->crs_x = x;
  137.             if (idx>=index)
  138.                 break;
  139.             else
  140.             {
  141.                 ed->crs_x = (x += ed->cw);
  142.                 idx++;
  143.             }
  144.         }
  145.         else
  146.             x += ed->cw;
  147.     }
  148.  
  149.     return (edit);
  150. }
  151.  
  152. static void draw_cursor(DIAINFO *info,EDINFO *ed)
  153. {
  154.     GRECT cursor,work;
  155.  
  156.     _calc_cursor(info,ed,&cursor);
  157.     if (rc_intersect(&desk,&cursor))
  158.     {
  159.         if (info->di_flag>=WINDOW)
  160.         {
  161.             window_first(info->di_win,&work);
  162.             while (work.g_w>0 && work.g_h>0)
  163.             {
  164.                 if (rc_intersect(&cursor,&work))
  165.                     rc_sc_invert(&work);
  166.                 window_next(info->di_win,&work);
  167.             }
  168.         }
  169.         else if (info->di_flag>CLOSED)
  170.             rc_sc_invert(&cursor);
  171.     }
  172. }
  173.  
  174. void _calc_cursor(DIAINFO *info,reg EDINFO *ed,reg GRECT *cursor)
  175. {
  176.     cursor->g_x = ed->crs_x;
  177.     cursor->g_y = ed->crs_y;
  178.  
  179.     if (info->di_insert)
  180.     {
  181.         cursor->g_y -= 1;
  182.         cursor->g_w = 1;
  183.         cursor->g_h = ed->ch+2;
  184.     }
  185.     else
  186.     {
  187.         cursor->g_w = ed->cw;
  188.         cursor->g_h = ed->ch;
  189.     }
  190. }
  191.  
  192. static EDINFO ed;
  193.  
  194. EDINFO *_cursor_off(DIAINFO *info)
  195. {
  196.     if (_edit_get_info(info->di_tree,info->di_ed_obj,info->di_ed_index,&ed)!=NULL)
  197.     {
  198.         if (!info->di_win->iconified && info->di_cursor)
  199.         {
  200.             if (info->di_flag>=WINDOW)
  201.                 wind_update(BEG_UPDATE);
  202.  
  203.             MouseOff();
  204.             draw_cursor(info,&ed);
  205.             MouseOn();
  206.  
  207.             if (info->di_flag>=WINDOW)
  208.                 wind_update(END_UPDATE);
  209.         }
  210.  
  211.         info->di_cursor = FALSE;
  212.         return (&ed);
  213.     }
  214.     else
  215.         return (NULL);
  216. }
  217.  
  218. static int get_editlen(DIAINFO *info)
  219. {
  220.     reg char *masc = info->di_tree[info->di_ed_obj].ob_spec.tedinfo->te_ptmplt, u = '_', c;
  221.     reg int len = 0;
  222.  
  223.     while ((c=*masc++)!='\0')
  224.         if (c==u) len++;
  225.     return (len);
  226. }
  227.  
  228. void _set_cursor(DIAINFO *info,int obj,int index)
  229. {
  230.     reg char *text;
  231.     reg int new_ob;
  232.  
  233.     if (obj<0)
  234.         obj = info->di_ed_obj;
  235.  
  236.     if (info->di_win->iconified || obj<0)
  237.     {
  238.         info->di_cursor = FALSE;
  239.         return;
  240.     }
  241.  
  242.     text = info->di_tree[obj].ob_spec.tedinfo->te_ptext;
  243.     if (index<0 && (index=info->di_ed_index)<0)
  244.         index = (int) strlen(text);
  245.     else
  246.         index = max(min(index,(int) strlen(text)),0);
  247.  
  248.     new_ob = (obj!=info->di_ed_obj);
  249.  
  250.     if (new_ob || index!=info->di_ed_index || info->di_cursor==FALSE)
  251.     {
  252.         if (new_ob)
  253.             _insert_history(info);
  254.  
  255.         if (info->di_flag>=WINDOW)
  256.             wind_update(BEG_UPDATE);
  257.         MouseOff();
  258.  
  259.         if (info->di_cursor)
  260.         {
  261.             _edit_get_info(info->di_tree,info->di_ed_obj,info->di_ed_index,&ed);
  262.             draw_cursor(info,&ed);
  263.             info->di_cursor = FALSE;
  264.         }
  265.  
  266.         info->di_ed_obj = obj;
  267.         if (info->di_insert==FALSE)
  268.             index = min(index,get_editlen(info)-1);
  269.         info->di_ed_index = index;
  270.  
  271.         if (info->di_drawn)
  272.         {
  273.             _edit_get_info(info->di_tree,obj,index,&ed);
  274.             draw_cursor(info,&ed);
  275.             info->di_cursor = TRUE;
  276.         }
  277.  
  278.         MouseOn();
  279.         if (info->di_flag>=WINDOW)
  280.             wind_update(END_UPDATE);
  281.  
  282.         if (new_ob)
  283.             strncpy(info->di_undobuff,ob_get_text(info->di_tree,info->di_ed_obj,0),MAX_EDIT-1);
  284.     }
  285. }
  286.  
  287. static void first_edit(DIAINFO *info)
  288. {
  289.     reg OBJECT *obj = info->di_tree;
  290.     reg int index= 0;
  291.  
  292.     if (info->di_ed_cnt<=1)
  293.         return;
  294.  
  295.     do
  296.     {
  297.         obj++;index++;
  298.         if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  299.         {
  300.             _set_cursor(info,index,0);
  301.             break;
  302.         }
  303.     }
  304.     while (!(obj->ob_flags & LASTOB));
  305. }
  306.  
  307. static void last_edit(DIAINFO *info)
  308. {
  309.     reg OBJECT *obj = info->di_tree;
  310.     reg int index,last;
  311.  
  312.     if (info->di_ed_cnt<=1)
  313.         return;
  314.  
  315.     index = last = 0;
  316.     do
  317.     {
  318.         obj++;index++;
  319.         if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  320.             last = index;
  321.     }
  322.     while (!(obj->ob_flags & LASTOB));
  323.  
  324.     if (last)
  325.         _set_cursor(info,last,0x1000);
  326. }
  327.  
  328. int _next_edit(DIAINFO *info,int first)
  329. {
  330.     reg int index = info->di_ed_obj;
  331.     reg OBJECT *obj = &info->di_tree[index];
  332.  
  333.     if (info->di_ed_cnt<=1)
  334.         return(FALSE);
  335.  
  336.     if (!(obj->ob_flags & LASTOB))
  337.     {
  338.         do
  339.         {
  340.             obj++;index++;
  341.             if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  342.             {
  343.                 _set_cursor(info,index,0x1000);
  344.                 return(TRUE);
  345.             }
  346.         }
  347.         while (!(obj->ob_flags & LASTOB));
  348.     }
  349.  
  350.     if (first)
  351.     {
  352.         first_edit(info);
  353.         _set_cursor(info,FAIL,0x1000);
  354.         return (TRUE);
  355.     }
  356.     else
  357.         return (FALSE);
  358. }
  359.  
  360. static void prev_edit(DIAINFO *info)
  361. {
  362.     reg int index = info->di_ed_obj;
  363.     reg OBJECT *obj = &info->di_tree[index];
  364.  
  365.     if (info->di_ed_cnt<=1)
  366.         return;
  367.  
  368.     do
  369.     {
  370.         obj--;index--;
  371.         if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  372.         {
  373.             _set_cursor(info,index,0x1000);
  374.             return;
  375.         }
  376.     } while (index>0);
  377.     
  378.     last_edit(info);
  379. }
  380.  
  381. static int cursor_handler(DIAINFO *info,int state,int scan,XEVENT *event)
  382. {
  383.     reg char *text = ob_get_text(info->di_tree,info->di_ed_obj,0);
  384.     reg int ascii;
  385.  
  386.     if (!(state & K_CTRL))
  387.     {
  388.         if (state & 3)
  389.         {
  390.             switch(scan)
  391.             {
  392.             case SCANESC:
  393.                 first_edit(info);
  394.                 insert_string(info,"");
  395.                 while (_next_edit(info,FALSE))
  396.                     insert_string(info,"");
  397.                 first_edit(info);
  398.                 _send_msg(info,FAIL,OBJC_EDITED,0,0);
  399.                 info->di_taken = FAIL;
  400.                 break;
  401.             case SCANBS:
  402.                 if (info->di_ed_index>0)
  403.                 {
  404.                     _cursor_off(info);
  405.                     strcpy(text,&text[info->di_ed_index]);
  406.                     ob_draw(info,info->di_ed_obj);
  407.                     _set_cursor(info,FAIL,0);
  408.                 }
  409.                 break;
  410.             case SCANDEL:
  411.                 _cursor_off(info);
  412.                 text[info->di_ed_index] = '\0';
  413.                 ob_draw(info,info->di_ed_obj);
  414.                 _set_cursor(info,FAIL,FAIL);
  415.                 break;
  416.             case SCANRET:
  417.             case SCANENTER:
  418.             case SCANTAB:
  419.                 prev_edit(info);
  420.                 break;
  421.             case SCANUP:
  422.                 first_edit(info);
  423.                 break;
  424.             case SCANHOME:
  425.                 last_edit(info);
  426.                 break;
  427.             case SCANDOWN:
  428.                 last_edit(info);
  429.             case SCANLEFT:
  430.                 _set_cursor(info,FAIL,0);
  431.                 break;
  432.             case SCANRIGHT:
  433.                 _set_cursor(info,FAIL,0x1000);
  434.                 break;
  435.             case SCANINS:
  436.                 ascii = ascii_box(info->di_title);
  437.                 _init_xformdo(event,NULL,FAIL);
  438.                 if (ascii)
  439.                     insert_char(info,ascii);
  440.                 break;
  441.             default:
  442.                 return(FALSE);
  443.             }
  444.         }
  445.         else
  446.         {
  447.             switch(scan)
  448.             {
  449.             case SCANESC:
  450.                 insert_string(info,"");
  451.                 break;
  452.             case SCANBS:
  453.                 if (info->di_ed_index>0)
  454.                     delete_char(info,info->di_ed_index-1);
  455.                 break;
  456.             case SCANDEL:
  457.                 delete_char(info,info->di_ed_index);
  458.                 break;
  459.             case SCANHOME:
  460.                 first_edit(info);
  461.                 break;
  462.             case SCANUP:
  463.                 prev_edit(info);
  464.                 break;
  465.             case SCANDOWN:
  466.             case SCANTAB:
  467.             case SCANENTER:
  468.                 _next_edit(info,TRUE);
  469.                 break;
  470.             case SCANINS:
  471.                 _cursor_off(info);
  472.                 info->di_insert = (info->di_insert) ? FALSE : TRUE;
  473.                 _set_cursor(info,FAIL,FAIL);
  474.                 break;
  475.             case SCANLEFT:
  476.                 _set_cursor(info,FAIL,max(info->di_ed_index-1,0));
  477.                 break;
  478.             case SCANRIGHT:
  479.                 _set_cursor(info,FAIL,info->di_ed_index+1);
  480.                 break;
  481.             default:
  482.                 return(FALSE);
  483.             }
  484.         }
  485.  
  486.         return(TRUE);
  487.     }
  488.     else
  489.         return(FALSE);
  490. }
  491.  
  492. static char ted_char(char valid, reg unsigned char c)
  493. {
  494.     switch (valid)
  495.     {
  496.     case 'l':
  497.     case 'L':
  498.         if (c>=16 && c<=25)
  499.             return (c);
  500.         else if (c>='0' && c<='9')
  501.             return (c - '0' + 16);
  502.         break;
  503.     case 'c':
  504.     case 'C':
  505.         if (strchr(".+-*/^()[]{}",c))
  506.             return (c);
  507.         else if (c==',')
  508.             return ('.');
  509.     case '0':
  510.     case '1':
  511.     case '2':
  512.     case '3':
  513.     case '4':
  514.     case '5':
  515.     case '6':
  516.     case '7':
  517.     case '8':
  518.     case '9':
  519.         if (c>='0' && c<=valid)
  520.             return (c);
  521.         break;
  522.     case 'h':
  523.         c = LowerChar(c);
  524.         if ((c>='0' && c<='9') || (c>='a' && c<='f'))
  525.             return (c);
  526.         break;
  527.     case 'H':
  528.         c = UpperChar(c);
  529.         if ((c>='0' && c<='9') || (c>='A' && c<='F'))
  530.             return (c);
  531.         break;
  532.     case 'N':
  533.         if (c>='0' && c<='9')
  534.             return (c);
  535.     case 'A':
  536.         c = UpperChar(c);
  537.         if ((c>='A' && c<='Z') || c==' ')
  538.             return (c);
  539.         break;
  540.     case 'n':
  541.         if (c>='0' && c<='9')
  542.             return (c);
  543.     case 'a':
  544.         c = LowerChar(c);
  545.         if ((c>='a' && c<='z') || c==' ')
  546.             return (c);
  547.         break;
  548.     case 'P':
  549.         if (c=='\?' || c=='*')
  550.             return (c);
  551.     case 'p':
  552.         if (c=='.' || c==':' || c=='\\')
  553.             return (c);
  554.     case 'F':
  555.         if ((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || strchr(" _!@#$%^&()+-=~\'`;\",<>|[]{}",c))
  556.             return (c);
  557.         break;
  558.     case 'U':
  559.         c = UpperChar(c);
  560.         if (c>=32 && c<=127)
  561.             return (c);
  562.         break;
  563.     case 'u':
  564.         c = LowerChar(c);
  565.         if (c>=32 && c<=127)
  566.             return (c);
  567.         break;
  568.     case 'V':
  569.         c = UpperChar(c);
  570.         if (c>=32)
  571.             return (c);
  572.         break;
  573.     case 'v':
  574.         c = LowerChar(c);
  575.         if (c>=32)
  576.             return (c);
  577.         break;
  578.     case 'w':
  579.     case 'W':
  580.         if (c>=32 && c<=127)
  581.             return (c);
  582.         break;
  583.     case 'y':
  584.     case 'Y':
  585.         if (c>=32)
  586.             return (c);
  587.         break;
  588.     case 'X':
  589.     default:
  590.         return (c);
  591.     }
  592.  
  593.     return ('\0');
  594. }
  595.  
  596. static void insert_string(DIAINFO *info,char *str)
  597. {
  598.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  599.     reg char c,v,*text = ted->te_ptext,*valid = ted->te_pvalid;
  600.     reg int len = get_editlen(info);
  601.  
  602.     _cursor_off(info);
  603.  
  604.     v = *valid++;
  605.     while (len>0 && *str!='\0')
  606.         if ((c=ted_char(v,*str++))!='\0')
  607.         {
  608.             *text++ = c;
  609.             if (*valid)
  610.                 v = *valid++;
  611.             len--;
  612.         }
  613.     *text = '\0';
  614.  
  615.     ob_draw(info,info->di_ed_obj);
  616.     _set_cursor(info,FAIL,0x1000);
  617. }
  618.  
  619. static void new_edit(DIAINFO *info, char *new, char *text, char *edit,int index, int len)
  620. {
  621.     char new_text[MAX_EDIT<<1],old_text[MAX_EDIT<<1];
  622.     reg EDINFO *ed;
  623.     reg char m,*s,*c,*n,*o;
  624.     reg int offset,width;
  625.     int len1,len2;
  626.  
  627.     if (strcmp(new,text))
  628.     {
  629.         n = new_text; o = old_text;
  630.         s = new; c = text;
  631.         while ((m=*edit++)!='\0')
  632.             if (m=='_')
  633.             {
  634.                 *n++ = *s++;
  635.                 *o++ = *c++;
  636.             }
  637.             else
  638.                 *n++ = *o++ = m;
  639.  
  640.         s = new_text; c = old_text;
  641.         while (*s++==*c++);
  642.  
  643.         s--;c--;
  644.         offset = (int) (s-new_text);
  645.  
  646.         len1 = (int) strlen(s);
  647.         len2 = (int) strlen(c);
  648.         if (len1!=len2)
  649.             width = max(len1,len2);
  650.         else
  651.         {
  652.             width = len1;
  653.             s += len1; c += len1;
  654.             while (*--s==*--c)
  655.                 width--;
  656.         }
  657.  
  658.         strncpy(text,new,len);
  659.  
  660.         ed = _cursor_off(info);
  661.         ed->text_x += offset*ed->cw;
  662.         ed->text_w = width*ed->cw;
  663.         ob_draw_chg(info,info->di_ed_obj,(GRECT *) &ed->text_x,FAIL,FALSE);
  664.     }
  665.  
  666.     _set_cursor(info,FAIL,index);
  667. }
  668.  
  669. static void delete_char(DIAINFO *info,int index)
  670. {
  671.     char buf[MAX_EDIT<<1];
  672.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  673.     reg char *text = ted->te_ptext;
  674.  
  675.     if (text[index]!='\0')
  676.     {
  677.         strcpy(buf,text);
  678.         strcpy(&buf[index],&text[index+1]);
  679.         new_edit(info,buf,text,ted->te_ptmplt,index,get_editlen(info));
  680.     }
  681. }
  682.  
  683. static int insert_char(DIAINFO *info,int scan)
  684. {
  685.     char buf[MAX_EDIT<<1];
  686.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  687.     reg char v,*text = ted->te_ptext,*valid = ted->te_pvalid;
  688.     reg int idx,offset,taken;
  689.  
  690.     offset = idx = min(get_editlen(info)-1,info->di_ed_index);
  691.     while (idx>=0 && *valid)
  692.     {
  693.         v = *valid++;
  694.         idx--;
  695.     }
  696.  
  697.     if ((taken=ted_char(v,scan))!=0)
  698.     {
  699.         strcpy(buf,text);
  700.  
  701.         if (info->di_insert)
  702.             strcpy(&buf[offset+1],text+offset);
  703.         else
  704.         {
  705.             valid = buf;
  706.             while (*valid++);
  707.             *valid++ = '\0';
  708.         }
  709.  
  710.         buf[offset] = taken;
  711.         new_edit(info,buf,text,ted->te_ptmplt,info->di_ed_index+1,get_editlen(info));
  712.         return (TRUE);
  713.     }
  714.     else
  715.         return (FALSE);
  716. }
  717.  
  718. void _insert_history(DIAINFO *info)
  719. {
  720.     reg char *str;
  721.  
  722.     if (info->di_ed_obj<=0)
  723.         return;
  724.     
  725.     str = ob_get_text(info->di_tree,info->di_ed_obj,0);
  726.  
  727.     if (str!=NULL && *str!='\0')
  728.     {
  729.         reg int i;
  730.  
  731.         for (i=0;i<HISTORY-1;i++)
  732.             if (!strcmp(history[i],str))
  733.                 return;
  734.  
  735.         for (i=(HISTORY-1);i>=1;i--)
  736.             strcpy(history[i],history[i-1]);
  737.  
  738.         strcpy(history[0],str);
  739.  
  740.         if (hist_index<(HISTORY-1) && history[hist_index+1][0])
  741.             hist_index++;
  742.     }
  743. }
  744.  
  745. static boolean clipbrd_save(DIAINFO *info,int mode)
  746. {
  747.     char path[MAX_PATH],*text,*crlf="\r\n";
  748.     int handle;
  749.  
  750.     if (scrp_path(path,"scrap.txt") && (handle=open(path,mode))>0)
  751.     {
  752.         text = ob_get_text(info->di_tree,info->di_ed_obj,0);
  753.  
  754. #ifdef __MINT_LIB__
  755.         write(handle,text,(unsigned) strlen(text));
  756.         write(handle,crlf,2);
  757. #else
  758.         write(handle,text,strlen(text));
  759.         write(handle,crlf,2);
  760. #endif
  761.  
  762.         close(handle);
  763.         scrp_changed(SCF_TEXT,0x2e545854l);    /* .TXT */
  764.  
  765.         return(TRUE);
  766.     }
  767.     else
  768.         return(FALSE);
  769. }
  770.  
  771. int _insert_buf(DIAINFO *info,char *text,int cat)
  772. {
  773.     char buf[MAX_EDIT];
  774.     reg char *line;
  775.     reg int len = 0;
  776.  
  777.     strncpy(buf,text,MAX_EDIT-1);
  778.     buf[MAX_EDIT-1] = '\0';
  779.  
  780.     if ((line=strpbrk(buf,"\r\n"))!=NULL)
  781.     {
  782.         len = (line[0]=='\r' && line[1]=='\n') ? 2 : 1;
  783.         *line = '\0';
  784.     }
  785.  
  786.     len += (int) strlen(buf);
  787.  
  788.     if (cat)
  789.     {
  790.         char str[MAX_EDIT<<1];
  791.  
  792.         strcpy(str,ob_get_text(info->di_tree,info->di_ed_obj,0));
  793.         strcat(str,buf);
  794.         strncpy(buf,str,MAX_EDIT-1);
  795.         buf[MAX_EDIT-1] = '\0';
  796.     }
  797.  
  798.     insert_string(info,buf);
  799.  
  800.     return (len);
  801. }
  802.  
  803. static void clipbrd_load(DIAINFO *info,boolean flag)
  804. {
  805.     char path[MAX_PATH],buf[MAX_EDIT];
  806.     int handle;
  807.  
  808.     if (scrp_path(path,"scrap.txt") && (handle=open(path,O_RDONLY))>0)
  809.     {
  810.         if (read(handle,buf,MAX_EDIT-1)>0);
  811.             _insert_buf(info,buf,flag);
  812.         close(handle);
  813.     }
  814. }
  815.  
  816. static boolean word_char(char c)
  817. {
  818.     if (c)
  819.         if (isalnum(c) || strchr(umlaute,c)!=NULL)
  820.             return(TRUE);
  821.     return(FALSE);
  822. }
  823.  
  824. static int insert_point(DIAINFO *info,char ascii)
  825. {
  826.     char edit_buf[MAX_EDIT];
  827.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  828.     reg char *masc = ted->te_ptmplt,*edit,c;
  829.     reg int idx = info->di_ed_index;
  830.  
  831.     edit = strcpy(edit_buf,ted->te_ptext);
  832.     while (*masc!='\0' && *masc++!='_');
  833.     masc--;
  834.  
  835.     if (strchr(",.;:/\\|",ascii)!=NULL && strchr(masc,ascii)!=NULL)
  836.     {
  837.         while (idx>0)
  838.             if (*masc++=='_')
  839.             {
  840.                 idx--;
  841.                 edit++;
  842.             }
  843.  
  844.         while (*masc++!='_');
  845.         masc--;
  846.  
  847.         if (strchr(masc,ascii)!=NULL)
  848.         {
  849.             while ((c=*masc++)!='\0')
  850.                 if (c==ascii)
  851.                     break;
  852.                 else if (c=='_')
  853.                     *edit++ = ' ';
  854.  
  855.             *edit++ = '\0';
  856.             insert_string(info,edit_buf);
  857.         }
  858.  
  859.         info->di_taken = TRUE;
  860.         return (TRUE);
  861.     }
  862.     else
  863.         return (FALSE);
  864. }
  865.  
  866. static int value[] = {7,8,9,4,5,6,1,2,3,0};
  867.  
  868. int _objc_edit_handler(DIAINFO *info,int state,int scan,XEVENT *event,int *edited)
  869. {
  870.     reg int old_obj = info->di_ed_obj;
  871.     reg int sn = (int) (((unsigned) scan)>>8),shft = (state&3);
  872.     reg char old_edit[MAX_EDIT],*text = ob_get_text(info->di_tree,old_obj,0);
  873.  
  874.     strcpy(old_edit,text);
  875.  
  876.     info->di_taken = TRUE;
  877.     if (cursor_handler(info,state,sn,event)==FALSE)
  878.     {
  879.         if (sn==SCANUNDO)
  880.             insert_string(info,info->di_undobuff);
  881.         else if ((state & K_ALT) && (sn>=0x67 && sn<=0x70))
  882.         {
  883.             _ascii *= 10;
  884.             _ascii += value[sn-0x67];
  885.             _ascii_digit++;
  886.             if (_ascii_digit==3 || _ascii>=26)
  887.             {
  888.                 insert_char(info,_ascii);
  889.                 _ascii = _ascii_digit = 0;
  890.             }
  891.         }
  892.         else if (state & K_CTRL)
  893.         {
  894.             reg char *c    = text+info->di_ed_index;
  895.  
  896.             switch (sn)
  897.             {
  898.             case CTRLLEFT:
  899.                 while (c>text && word_char(*(--c)));
  900.                 while (c>text && !word_char(*(--c)));
  901.                 _set_cursor(info,FAIL,(c>text) ? (int) (c - text + 1) : 0);
  902.                 break;
  903.             case CTRLRIGHT:
  904.                 while (word_char(*c++));
  905.                 if (*(--c) != '\0')
  906.                 {
  907.                     while (!word_char(*c++));
  908.                     if (*(--c) != '\0')
  909.                         _set_cursor(info,FAIL,(int) (c - text));
  910.                 }
  911.                 else
  912.                     _set_cursor(info,FAIL,(int) (c - text));
  913.                 break;
  914.             case SCANUP:
  915.                 {
  916.                     int o_i = hist_index;
  917.                     _insert_history(info);
  918.                     if (shft)
  919.                     {
  920.                         reg size_t n = strlen(text);
  921.                         if (n)
  922.                         {
  923.                             reg int i;
  924.                             for (i=(hist_index!=o_i) ? 1 : 0;i<HISTORY;i++)
  925.                                 if (!strncmp(history[i],text,n))
  926.                                 {
  927.                                     insert_string(info,history[i]);
  928.                                     hist_index = i;
  929.                                     break;
  930.                                 }
  931.                         }
  932.                     }
  933.                     else
  934.                     {
  935.                         if ((hist_index<(HISTORY-1)) && (history[hist_index+1][0]))
  936.                             hist_index++;
  937.                         insert_string(info,history[hist_index]);
  938.                     }
  939.                 }
  940.                 break;
  941.             case SCANDOWN:
  942.                 _insert_history(info);
  943.                 if (shft)
  944.                 {
  945.                     reg size_t n = strlen(text);
  946.                     if (n)
  947.                     {
  948.                         reg int i;
  949.                         for (i=(HISTORY-1);i>=0;i--)
  950.                             if (!strncmp(history[i],text,n))
  951.                             {
  952.                                 insert_string(info,history[i]);
  953.                                 hist_index = i;
  954.                                 break;
  955.                             }
  956.                     }
  957.                 }
  958.                 else
  959.                 {
  960.                     if (hist_index>0 && history[hist_index-1][0])
  961.                         hist_index--;
  962.                     insert_string(info,history[hist_index]);
  963.                 }
  964.                 break;
  965.             default:
  966.                 {
  967.                     int ascii = scan_2_ascii(scan,state),flag;
  968.  
  969.                     switch (ascii)
  970.                     {
  971.                     case 'X':
  972.                     case 'C':
  973.                         if (shft)
  974.                             flag = clipbrd_save(info,O_WRONLY|O_APPEND|O_CREAT);
  975.                         else
  976.                         {
  977.                             scrp_clear(0);
  978.                             flag = clipbrd_save(info,O_WRONLY|O_CREAT);
  979.                         }
  980.  
  981.                         if (flag && ascii=='X')
  982.                         {
  983.                             _cursor_off(info);
  984.                             ob_get_text(info->di_tree,info->di_ed_obj,1);
  985.                             ob_draw(info,info->di_ed_obj);
  986.                             _set_cursor(info,FAIL,FAIL);
  987.                         }
  988.                         break;
  989.                     case 'V':
  990.                         clipbrd_load(info,(shft) ? TRUE : FALSE);
  991.                         break;
  992.                     default:
  993.                         info->di_taken = FALSE;
  994.                         break;
  995.                     }
  996.                 }
  997.                 break;
  998.             }
  999.         }
  1000.         else if (!(state & K_ALT))
  1001.         {
  1002.             if (insert_point(info,scan_2_ascii(scan,state))==FALSE)
  1003.                 info->di_taken = insert_char(info,scan);
  1004.         }
  1005.         else
  1006.             info->di_taken = FALSE;
  1007.     }
  1008.  
  1009.     if (info->di_taken==FAIL)
  1010.         *edited = FAIL;
  1011.     else if (info->di_taken && old_obj==info->di_ed_obj && strcmp(old_edit,text))
  1012.         *edited = TRUE;
  1013.     else
  1014.         *edited = FALSE;
  1015.  
  1016.     return (FAIL);
  1017. }
  1018.  
  1019. char ascii_box(char *title)
  1020. {
  1021.     static int fix = TRUE, open = FALSE;
  1022.     int exit;
  1023.  
  1024.     if (open)
  1025.         return (0);
  1026.  
  1027.     if (fix)
  1028.     {
  1029.         rsrc_calc(ascii_tree,SCALING,8,16);
  1030.         fix = FALSE;
  1031.     }
  1032.  
  1033.     open = TRUE;
  1034.     exit = xdialog(ascii_tree,title,NULL,NULL,TRUE,FALSE,AUTO_DIAL|MODAL|NO_ICONIFY);
  1035.     open = FALSE;
  1036.  
  1037.     if (exit>0)
  1038.     {
  1039.         if (exit!=CANCEL)
  1040.         {
  1041.             int x,ox,d,ascii;
  1042.  
  1043.             _mouse_pos(&x,&d);
  1044.             objc_offset(ascii_tree,exit,&ox,&d);
  1045.             _no_click();
  1046.  
  1047.             ascii = (exit - ASC0)<<5;
  1048.             if ((d = x-ox)>=0)
  1049.                 ascii += d/gr_cw;
  1050.             ascii = min(max(ascii,0),255);
  1051.  
  1052.             return (ascii);
  1053.         }
  1054.     }
  1055.  
  1056.     return (0);
  1057. }
  1058.  
  1059. #endif
  1060.